package org.gdstash.ui.table;

import org.gdstash.file.DDSLoader;
import org.gdstash.item.GDItem;
import org.gdstash.ui.GDStashFrame;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class GDItemNameTableModel extends DefaultTableModel {
    private List<GDItem> data;
    private GDItemNameRow[] rows;
    private Comparator<GDItemNameRow> comparator;
    private boolean inclFaction;

    public GDItemNameTableModel(final List<GDItem> data, final boolean inclFaction) {
        this.data = data;
        this.inclFaction = inclFaction;
        this.comparator = null;
        this.adjustUI();
    }

    public void adjustUI() {
        GDItemNameRow.updateColumnNames();
        this.setColumnIdentifiers(GDItemNameRow.columnNames);
        this.setData(this.data);
    }

    public void setData(final List<GDItem> data) {
        this.data = data;
        this.rows = null;
        if (data == null) {
            return;
        }
        final int size = data.size();
        this.rows = new GDItemNameRow[size];
        final GDItem.LabelInfo liEmpty = new GDItem.LabelInfo();
        liEmpty.text = "";
        int i = 0;
        GDItem.LabelInfo li = null;
        for (final GDItem item : data) {
            this.rows[i] = new GDItemNameRow();
            BufferedImage img = item.getFullImage();
            this.rows[i].item = item;
            this.rows[i].baseName = item.getBaseName();
            if (img != null) {
                if (GDStashFrame.iniConfig.sectUI.graphicScale != 100) {
                    final int w = img.getWidth() * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
                    final int h = img.getHeight() * GDStashFrame.iniConfig.sectUI.graphicScale / 100;
                    img = DDSLoader.getScaledImage(img, w, h);
                }
                this.rows[i].icon = new ImageIcon(img);
            }
            li = item.getCompleteNameInfo(this.inclFaction, true);
            if (li == null) {
                li = liEmpty;
            }
            this.rows[i].name = li;
            li = item.getRequiredLevelInfo();
            if (li == null) {
                li = liEmpty;
            }
            this.rows[i].level = li;
            ++i;
        }
        if (this.comparator != null) {
            Arrays.<GDItemNameRow>sort(this.rows, this.comparator);
        }
        this.fireTableDataChanged();
    }

    public void updateRow(final int row, final GDItem item) {
        if (this.data == null) {
            return;
        }
        this.data.set(row, item);
        this.setData(this.data);
    }

    @Override
    public void removeRow(final int row) {
        if (row < 0) {
            return;
        }
        final GDItem item = this.rows[row].item;
        this.data.remove(item);
        this.setData(this.data);
    }

    @Override
    public int getRowCount() {
        if (this.rows == null) {
            return 0;
        }
        return this.rows.length;
    }

    @Override
    public int getColumnCount() {
        return GDItemNameRow.columnNames.length;
    }

    @Override
    public String getColumnName(final int column) {
        return GDItemNameRow.columnNames[column];
    }

    @Override
    public Object getValueAt(final int row, final int column) {
        if (this.rows == null) {
            return null;
        }
        if (row < 0) {
            return null;
        }
        if (row >= this.rows.length) {
            return null;
        }
        if (this.rows[row] == null) {
            return null;
        }
        if (column == 0) {
            return this.rows[row].icon;
        }
        if (column == 1) {
            return this.rows[row].name.text;
        }
        if (column == 2) {
            return this.rows[row].level.text;
        }
        return null;
    }

    @Override
    public boolean isCellEditable(final int row, final int column) {
        return false;
    }

    @Override
    public void setValueAt(final Object value, final int row, final int column) {
        if (!this.isCellEditable(row, column)) {
            return;
        }
        if (this.rows == null) {
            return;
        }
        if (row < 0) {
            return;
        }
        if (row >= this.rows.length) {
            return;
        }
        if (this.rows[row] == null) {
            return;
        }
        if (column == 0) {
            this.rows[row].icon = (ImageIcon) value;
        }
        if (column == 1) {
            this.rows[row].name.text = (String) value;
        }
        if (column == 2) {
            this.rows[row].level.text = (String) value;
        }
    }

    @Override
    public Class getColumnClass(final int column) {
        return GDItemNameRow.COLUMN_CLASSES[column];
    }

    public String getCellText(final int row, final int column) {
        if (this.rows == null) {
            return "";
        }
        if (row < 0) {
            return "";
        }
        if (row >= this.rows.length) {
            return "";
        }
        if (this.rows[row] == null) {
            return "";
        }
        if (column == 1) {
            return this.rows[row].name.text;
        }
        if (column == 2) {
            return this.rows[row].level.text;
        }
        return "";
    }

    public Color getCellTextColor(final int row, final int column) {
        if (this.rows == null) {
            return Color.BLACK;
        }
        if (row < 0) {
            return Color.BLACK;
        }
        if (row >= this.rows.length) {
            return Color.BLACK;
        }
        if (this.rows[row] == null) {
            return Color.BLACK;
        }
        if (column == 1) {
            return this.rows[row].name.foreground;
        }
        if (column == 2) {
            return this.rows[row].level.foreground;
        }
        return Color.BLACK;
    }

    public Color getCellBackgroundColor(final int row, final int column) {
        if (this.rows == null) {
            return Color.WHITE;
        }
        if (row < 0) {
            return Color.WHITE;
        }
        if (row >= this.rows.length) {
            return Color.WHITE;
        }
        if (this.rows[row] == null) {
            return Color.WHITE;
        }
        if (column == 1) {
            return this.rows[row].name.background;
        }
        if (column == 2) {
            return this.rows[row].name.background;
        }
        return Color.WHITE;
    }

    public GDItem getItem(final int row) {
        if (this.rows == null) {
            return null;
        }
        if (row < 0) {
            return null;
        }
        if (row >= this.rows.length) {
            return null;
        }
        if (this.rows[row] == null) {
            return null;
        }
        return this.rows[row].item;
    }

    public void sort(final Comparator<GDItemNameRow> comp) {
        if (comp == null) {
            return;
        }
        this.comparator = comp;
        if (this.rows == null) {
            return;
        }
        Arrays.<GDItemNameRow>sort(this.rows, this.comparator);
    }
}
